OpenBao Admin & Operations Guide
Comprehensive documentation for the Secunetics OpenBao infrastructure deployed on 10.11.11.123 (vault.secunetics.net).
1. Architecture Overview
- Platform: OpenBao (FOSS Fork of HashiCorp Vault)
- Deployment: Docker Compose (Single Node)
- Storage Backend: Integrated Raft Storage (Persistent local volume)
- Host Machine:
lab-microservices(10.11.11.123) - Domain:
vault.secunetics.net - Authentication: Google Workspace OIDC (Humans), AppRole (Machines)
2. Deployment & Configuration
The system is deployed via Docker. The directory structure on the host machine is:
~/openbao/
├── docker-compose.yml
├── config/
│ ├── bao.hcl
│ ├── bao.crt (Signed by Lab CA)
│ └── bao.key
├── data/ (Persistent Raft DB)
└── logs/ (Audit logs)
docker-compose.yml
version: '3.8'
services:
openbao:
image: openbao/openbao:latest
container_name: openbao
ports:
- "443:8200"
- "8201:8201"
restart: unless-stopped
command: server
environment:
BAO_ADDR: "https://127.0.0.1:8200"
BAO_API_ADDR: "https://127.0.0.1:8200"
volumes:
- ./config:/openbao/config
- ./data:/openbao/data
- ./logs:/openbao/logs
config/bao.hcl
ui = true
storage "raft" {
path = "/openbao/data"
node_id = "bao-node-1"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = "false"
tls_cert_file = "/openbao/config/bao.crt"
tls_key_file = "/openbao/config/bao.key"
tls_disable_client_certs = "true" # Prevents browser mTLS popups
}
api_addr = "https://10.11.11.123"
cluster_addr = "https://127.0.0.1:8201"
# Declarative Audit Device
audit "file" "audit-log" {
description = "Shared lab audit log"
options = {
file_path = "/openbao/logs/audit.log"
}
}
3. Initialization & Unsealing
OpenBao uses a master key to encrypt data. When the container starts or restarts, it is sealed and requires manual intervention to unlock.
How to Unseal (Do this after every reboot)
Log into the host machine and execute the unseal command three times, providing 3 different unseal keys:
sudo docker exec -it openbao bao operator unseal
Emergency Rebuild (Complete Data Loss)
If you lose the data volume or deploy to a new server, start the container and run:
sudo docker exec -it openbao bao operator init
SAVE THE 5 UNSEAL KEYS AND INITIAL ROOT TOKEN IMMEDIATELY.
4. TLS Certificates (Crucial Permissions)
OpenBao requires HTTPS. Certificates are generated via OpenSSL and signed by the internal Lab CA. Important: The OpenBao container runs as a restricted user (UID 100), not root.
Fixing Certificate Permission Denied Errors
If OpenBao crashes on startup with a TLS read error, the host machine permissions are wrong. Run this on the host:
sudo chown 100:100 config/bao.key config/bao.crt
sudo chmod 600 config/bao.key
sudo chmod 644 config/bao.crt
sudo docker restart openbao
5. Policies & Secrets Engines
To configure policies, drop into the container and bypass TLS verification for the local session:
sudo docker exec -it openbao sh
export BAO_ADDR="https://127.0.0.1:8200"
export BAO_SKIP_VERIFY="true"
bao login # (Use Root Token)
The Shared Engine
Users and scripts operate out of a KV-V2 engine located at lab-shared/. To recreate it:
bao secrets enable -path=lab-shared kv-v2
The Developer Policy (dev-policy)
bao policy write dev-policy - <<EOF
# Allow full access to shared secrets
path "lab-shared/data/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "lab-shared/metadata/*" {
capabilities = ["read", "list", "delete"]
}
# Allow users to manage their AppRole SecretIDs in the browser
path "auth/approle/role/lab-shared-app/role-id" {
capabilities = ["read"]
}
path "auth/approle/role/lab-shared-app/secret-id" {
capabilities = ["update"]
}
EOF
6. Google Workspace SSO (OIDC)
Human access is governed by Google SSO locked to the secunetics.com domain.
OIDC Setup Commands
bao auth enable oidc
# Configure the provider
bao write auth/oidc/config \
oidc_discovery_url="https://accounts.google.com" \
oidc_client_id="<GCP_CLIENT_ID>" \
oidc_client_secret="<GCP_CLIENT_SECRET>" \
default_role="google-user"
# Create the standard user role (Maps to dev-policy)
bao write auth/oidc/role/google-user - <<EOF
{
"user_claim": "email",
"oidc_scopes": ["email", "profile"],
"allowed_redirect_uris": [
"https://vault.secunetics.net/ui/vault/auth/oidc/oidc/callback",
"http://localhost:8250/oidc/callback"
],
"bound_claims": { "hd": "secunetics.com" },
"policies": ["dev-policy"],
"ttl": "8h"
}
EOF
# Create the Admin Role (Requires explicit email match)
bao write auth/oidc/role/admin-user - <<EOF
{
"user_claim": "email",
"oidc_scopes": ["email", "profile"],
"allowed_redirect_uris": [
"https://vault.secunetics.net/ui/vault/auth/oidc/oidc/callback",
"http://localhost:8250/oidc/callback"
],
"bound_claims": { "email": "YOUR_EMAIL@secunetics.com" },
"policies": ["admin-policy"],
"ttl": "8h"
}
EOF
7. AppRole (Machine Identities)
Microservices authenticate using AppRole. Users self-serve their SecretID via the Web UI Browser CLI.
Admin Setup: Creating the AppRole
bao auth enable approle
bao write auth/approle/role/lab-shared-app \
secret_id_ttl=0 \
token_num_uses=0 \
token_ttl=1h \
token_max_ttl=4h \
policies="dev-policy"
User Workflow: Generating Credentials in Web CLI
Users execute these in the Browser terminal (>_):
# Get the Role ID
read auth/approle/role/lab-shared-app/role-id
# Generate a Secret ID (Must use -f flag!)
write -f auth/approle/role/lab-shared-app/secret-id
8. Routine Maintenance
Audit Logs
Audit logging is strictly enabled via the bao.hcl file. The log file resides on the host at ~/openbao/logs/audit.log.
Action Required: Configure logrotate on the Ubuntu host machine to rotate and compress this file weekly, or it will eventually fill the host storage.
Raft Snapshots (Backups)
To take a backup of the encrypted database, run:
export BAO_ADDR="https://vault.secunetics.net"
bao login -method=oidc -role=admin-user
bao operator raft snapshot save bao_backup_$(date +%F).snap
TLS Certificate Renewal
Before the lab CA certificate expires:
- Generate a new CSR using the original
csr.conf(ensure SANs are included). - Sign it with the Lab CA.
- Replace
bao.crtin the config directory. - Run
sudo chown 100:100 config/bao.crt. - Restart the container and unseal.